package com.rui.study.micro.oauth2.service.impl;

import com.rui.study.commons.model.BizException;
import com.rui.study.commons.model.Result;
import com.rui.study.commons.util.JwtUtil;
import com.rui.study.commons.util.MD5Util;
import com.rui.study.micro.oauth2.external.api.KeyApi;
import com.rui.study.micro.oauth2.mapper.AccountMapper;
import com.rui.study.micro.oauth2.model.AccountPo;
import com.rui.study.micro.oauth2.service.AccountService;
import com.rui.study.micro.oauth2.util.StatusCode;
import io.jsonwebtoken.Claims;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
public class AccountServiceImpl implements AccountService {

    private static final Logger LOGGER = LoggerFactory.getLogger(AccountServiceImpl.class);

    @Autowired
    private AccountMapper accountMapper;

    @Autowired
    private KeyApi keyApi;

    @Value("${token.local.iss}")
    private String iss;

    @Value("${token.local.secret}")
    private String secret;

    @Override
    public String auth(String username, String password) {
        // 单因子认证
        AccountPo accountPo = accountMapper.selectAccount(username);
        if (accountPo == null) {
            throw new BizException(StatusCode.AUTHENTICATION_FAILED);
        }
        // 获取盐值
        String accountId = accountPo.getAccountId();
        Result<String> _result_salt = keyApi.getSalt(accountId);
        if (_result_salt.hasError()) {
            throw new BizException(_result_salt.getStatus(), _result_salt.getMessage());
        }
        String salt = _result_salt.getData();
        // 密码验证
        String saltedPwd = MD5Util.encrypt(password + salt);
        if (!saltedPwd.equals(accountPo.getPassword())) {
            throw new BizException(StatusCode.AUTHENTICATION_FAILED);
        }

        /* 产生Jwt */
        Map<String, Object> claims = new HashMap<>();
        claims.put("accountId", accountId);
        String jwt = JwtUtil.build(iss, "用户登录", "", 60 * 1000, claims, secret);
        LOGGER.info("Succeed to login and get the jwt [{}] by [{}]", jwt, username);
        return jwt;
    }

    @Override
    public String check(String token) {
        Claims claims = JwtUtil.parse(token, secret);
        String accountId = null;
        if (claims != null)
            accountId = String.valueOf(claims.get("accountId"));
        return accountId;
    }
}
